package com.acgist.polaris;

import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>配置</p>
 * 
 * @author acgist
 */
public final class Config {

	private static final Logger LOGGER = LoggerFactory.getLogger(Config.class);
	
	private static final Config INSTANCE = new Config();

	public static final Config getInstance() {
		return INSTANCE;
	}
	
	/**
	 * <p>配置文件：{@value}</p>
	 */
	private static final String CONFIG_PATH = "/config.properties";
	
	/**
	 * <p>数据大小比例：{@value}</p>
	 */
	public static final int DATA_SCALE = 1024;
	/**
	 * <p>1KB数据大小：{@value}</p>
	 * <p>1KB = 1024B</p>
	 */
	public static final int ONE_KB = DATA_SCALE;
	/**
	 * <p>1MB数据大小：{@value}</p>
	 * <p>1MB = 1024KB = 1024 * 1024B</p>
	 */
	public static final int ONE_MB = DATA_SCALE * ONE_KB;
	
	/**
	 * <p>软件名称</p>
	 */
	private String name;
	/**
	 * <p>软件版本</p>
	 */
	private String version;
	/**
	 * <p>软件英文名称</p>
	 */
	private String nameEn;
	/**
	 * <p>算法名称</p>
	 */
	private String algo;
	/**
	 * <p>压缩文件后缀</p>
	 */
	private String suffix;
	
	private Config() {
		this.init();
		this.systemInfo();
	}
	
	/**
	 * <p>压缩数据类型</p>
	 */
	public enum Type {
		
		/** 数据流 */
		STREAM((byte) 0),
		/** 文件 */
		FILE((byte) 1);
		
		/**
		 * <p>数据类型</p>
		 */
		private final byte value;

		private Type(byte value) {
			this.value = value;
		}
		
		public byte value() {
			return this.value;
		}
		
		public static final Type of(byte value) {
			final Type[] types = Type.values();
			for (Type type : types) {
				if(type.value == value) {
					return type;
				}
			}
			return null;
		}
		
	}
	
	/**
	 * <p>算法版本</p>
	 * <p>不同版本不会兼容</p>
	 */
	public enum Version {
		
		VERSION_1_0_0("1.0.0");
		
		/**
		 * <p>版本编号</p>
		 */
		private final String version;

		private Version(String version) {
			this.version = version;
		}
		
		/**
		 * <p>获取版本编号</p>
		 * 
		 * @return 版本编号
		 */
		public String version() {
			return this.version;
		}
		
		/**
		 * <p>通过版本编号获取算法版本</p>
		 * 
		 * @param version 版本编号
		 * 
		 * @return 算法版本
		 */
		public static final Version of(String version) {
			final Version[] values = Version.values();
			for (Version value : values) {
				if(value.version.equals(version)) {
					return value;
				}
			}
			return null;
		}
		
		/**
		 * <p>获取最新版本</p>
		 * 
		 * @return 最新版本
		 */
		public static final Version newest() {
			return VERSION_1_0_0;
		}
		
	}
	
	/**
	 * <p>动作</p>
	 */
	public enum Action {
		
		/** 压缩 */
		GZ,
		/** 解压 */
		UNGZ,
		/** 查看 */
		LIST;
		
	}

	/**
	 * <p>初始化配置</p>
	 */
	private void init() {
		final Properties properties = new Properties();
		try (final var input = new InputStreamReader(Config.class.getResourceAsStream(CONFIG_PATH), StandardCharsets.UTF_8)) {
			properties.load(input);
		} catch (Exception e) {
			LOGGER.error("配置加载异常", e);
		}
		this.name = properties.getProperty("acgist.name", "勾陈");
		this.version = properties.getProperty("acgist.version", "1.0.0");
		this.nameEn = properties.getProperty("acgist.name.en", "polaris");
		this.algo = properties.getProperty("acgist.algo", "polaris");
		this.suffix = properties.getProperty("acgist.suffix", "gc");
	}
	
	/**
	 * <p>系统信息</p>
	 */
	private void systemInfo() {
		// 系统信息
		final var runtime = Runtime.getRuntime();
		LOGGER.info("操作系统名称：{}", System.getProperty("os.name"));
		LOGGER.info("操作系统架构：{}", System.getProperty("os.arch"));
		LOGGER.info("操作系统版本：{}", System.getProperty("os.version"));
		LOGGER.info("操作系统可用处理器数量：{}", runtime.availableProcessors());
		LOGGER.info("Java版本：{}", System.getProperty("java.version"));
		LOGGER.info("Java主目录：{}", System.getProperty("java.home"));
		LOGGER.info("Java包目录：{}", System.getProperty("java.library.path"));
		LOGGER.info("虚拟机名称：{}", System.getProperty("java.vm.name"));
		LOGGER.info("虚拟机最大内存：{}", Tools.formatSize(runtime.maxMemory()));
		LOGGER.info("虚拟机已用内存：{}", Tools.formatSize(runtime.totalMemory()));
		LOGGER.info("虚拟机空闲内存：{}", Tools.formatSize(runtime.freeMemory()));
		LOGGER.info("用户主目录：{}", System.getProperty("user.home"));
		LOGGER.info("用户工作目录：{}", System.getProperty("user.dir"));
		LOGGER.info("文件编码：{}", System.getProperty("file.encoding"));
		// 软件信息
		LOGGER.info("软件名称：{}", this.name);
		LOGGER.info("软件版本：{}", this.version);
		LOGGER.info("软件英文名称：{}", this.nameEn);
		LOGGER.info("算法名称：{}", this.algo);
		LOGGER.info("压缩文件后缀：{}", this.suffix);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getNameEn() {
		return nameEn;
	}

	public void setNameEn(String nameEn) {
		this.nameEn = nameEn;
	}

	public String getAlgo() {
		return algo;
	}

	public void setAlgo(String algo) {
		this.algo = algo;
	}

	public String getSuffix() {
		return suffix;
	}

	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}
	
}
